package way

import (
	"sync"
)

type Parallel struct {
	Max        int
	Tasks      []func()
	Wg         *sync.WaitGroup
	WorkerChan chan int
}

func NewParallel(max int, tasks ...func()) *Parallel {
	c := &Parallel{
		Max:        max,
		Wg:         &sync.WaitGroup{},
		WorkerChan: make(chan int, max),
		Tasks:      tasks,
	}
	return c
}

func (c *Parallel) Add(task func()) {
	c.Tasks = append(c.Tasks, task)
}

func (c *Parallel) Run() {
	for i := 0; i < c.Max; i++ {
		c.WorkerChan <- i
	}
	for i, task := range c.Tasks {
		c.Wg.Add(1)
		go func(task func(), i int) {
			worker := <-c.WorkerChan
			task()
			c.WorkerChan <- worker
			c.Wg.Done()
		}(task, i)
	}
	c.Wg.Wait()
}
